#include "delay.h"
#include "do_mqtt.h"
#include "w55mh32.h"
#include <misc.h>
#include <w55mh32_rcc.h>
#include <w55mh32_tim.h>

/**
 * @brief Initialize TIM2/4 timer, configured for 1ms period interrupt
 * @note Implementation logic:
 * 1. Enable TIM2/4 clock, configure timer prescaler and period to generate 1ms
 * interrupt
 * 2. Enable TIM2 update interrupt, configure NVIC interrupt priority, start
 * timer Interrupt period calculation: Timer clock = 216MHz, after prescaling by
 * 21600, counting clock = 216MHz/21600 = 10000Hz Period value is 10-1, so
 * interrupt period = 10 / 10000Hz = 1ms
 */
void timer_init(void) {
  TIM_TimeBaseInitTypeDef
      tim_time_base_init;     // TIM2 time base configuration structure
  NVIC_InitTypeDef nvic_init; // NVIC interrupt configuration structure

  // Enable TIM2 clock (APB1 bus)
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  // Configure TIM2 time base parameters: 1ms interrupt period
  tim_time_base_init.TIM_Prescaler = 21600 - 1; // Prescaler value (21600-1)
  tim_time_base_init.TIM_CounterMode = TIM_CounterMode_Up; // Up counting mode
  tim_time_base_init.TIM_Period =
      10 - 1; // Period value (10-1),配合预分频实现1ms中断
  tim_time_base_init.TIM_ClockDivision = TIM_CKD_DIV1; // Clock division factor
  TIM_TimeBaseInit(TIM2, &tim_time_base_init);         // Initialize TIM2

  // Enable TIM2 update interrupt (generated when counter overflows)
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

  // Start TIM2 timer
  TIM_Cmd(TIM2, ENABLE);

  // Configure NVIC: enable TIM2 interrupt, set priority
  nvic_init.NVIC_IRQChannel = TIM2_IRQn;           // TIM2 interrupt channel
  nvic_init.NVIC_IRQChannelPreemptionPriority = 0; // Preemption priority 0
  nvic_init.NVIC_IRQChannelSubPriority = 1;        // Sub priority 1
  nvic_init.NVIC_IRQChannelCmd = ENABLE;           // Enable interrupt channel
  NVIC_Init(&nvic_init);                           // Initialize NVIC
}

void timer4_init(void) {
  TIM_TimeBaseInitTypeDef
      tim_time_base_init;     // TIM4 time base configuration structure
  NVIC_InitTypeDef nvic_init; // NVIC interrupt configuration structure

  // Enable TIM4 clock (APB1 bus)
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

  // Configure TIM4 time base parameters: 1ms interrupt period
  tim_time_base_init.TIM_Prescaler = 21600 - 1; // Prescaler value (21600-1)
  tim_time_base_init.TIM_CounterMode = TIM_CounterMode_Up; // Up counting mode
  tim_time_base_init.TIM_Period =
      10 - 1; // Period value (10-1),配合预分频实现1ms中断
  tim_time_base_init.TIM_ClockDivision = TIM_CKD_DIV1; // Clock division factor
  TIM_TimeBaseInit(TIM1, &tim_time_base_init);         // Initialize TIM4

  // Enable TIM4 update interrupt (generated when counter overflows)
  TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);

  // Start TIM4 timer
  TIM_Cmd(TIM4, ENABLE);

  // Configure NVIC: enable TIM4 interrupt, set priority
  nvic_init.NVIC_IRQChannel = TIM4_IRQn;           // TIM4 interrupt channel
  nvic_init.NVIC_IRQChannelPreemptionPriority = 0; // Preemption priority 0
  nvic_init.NVIC_IRQChannelSubPriority = 1;        // Sub priority 1
  nvic_init.NVIC_IRQChannelCmd = ENABLE;           // Enable interrupt channel
  NVIC_Init(&nvic_init);                           // Initialize NVIC
}

/**
 * @brief TIM4 interrupt service function (handles delay timing)
 * @note Triggered every 1ms, reduces delay timer, ends delay when reaching 0
 */
void TIM4_IRQHandler(void) {
  if (TIM_GetITStatus(TIM4, TIM_IT_Update) == SET) {
    mqtt_tick();
    TIM_ClearITPendingBit(TIM4, TIM_IT_Update); // Clear interrupt flag
  }
}
